package net.warl0ck.mjjp;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicLabelUI;

public interface MJTypes {
	public class MJJPInfo{
		public String name;
		public String date;
		public String version;
		public String desc;
		public String text;
		public String copy;
		public String url;
		public String mail;
		public String icq;
		
		public MJJPInfo(String locale){
			name = "MahJong Java Player";
			date = "15.06.2009";
			version = "0.1.35 freeware";
			desc = MJUtils.getLocaleStr("description",locale);
			text = MJUtils.getLocaleStr("add_text",locale);
			copy = "Written by WarL0ck";
			url = "http://www.warl0ck.net";
			mail = "main@warl0ck.net";
			icq = "37548196";
		}
	}
	public class MJConst{
		public int max_disc_cols = 8;
	}
	public class MJParams{
		private String url;
		private String typetail;
		private String[] valid_types;
		private int maxtail;
		private String lang;
		private String locale;
		private int font;
		
		public MJParams(){
			init();
		}
		private void init() {
			setUrl("");
			setValidTypes(new String[]{"base","small","4winds"});
			setTypeTail("base");
			setMaxTail("14");
			setLang("russian");
			setFont("12");
		}
		public void loadParams(JApplet appl){
			if (! appl.getParameter("url").isEmpty()) setUrl(appl.getParameter("url"));
			if ((appl.getParameter("type")!=null) && (! appl.getParameter("type").isEmpty())){
				if (testType(appl.getParameter("type")))
					setTypeTail(appl.getParameter("type").toLowerCase());
			}
			if ((appl.getParameter("maxtail")!=null) && (! appl.getParameter("maxtail").isEmpty())){
				setMaxTail(appl.getParameter("maxtail"));
			}
			if ((appl.getParameter("lang")!=null) && (! appl.getParameter("lang").isEmpty())){
				setLang(appl.getParameter("lang"));
			}
			if ((appl.getParameter("font")!=null) && (! appl.getParameter("font").isEmpty())){
				setFont(appl.getParameter("font"));
			}
		}
		private boolean testMaxTail(String parameter) {
			try{
				Integer.parseInt(parameter);
				return true;
			} catch (NumberFormatException e) {
				return false;
			}
		}
		public boolean testParams(){
			boolean res = true;
			if (getUrl().equals("")) res = false;
			return res;
		}
		public void setUrl(String url) {
			this.url = url;
		}

		public String getUrl() {
			return url;
		}
		public void setTypeTail(String typetail) {
			this.typetail = typetail;
		}
		public String getTypeTail() {
			return typetail;
		}
		public void setValidTypes(String[] valid_types) {
			this.valid_types = valid_types;
		}
		public boolean testType(String type){
			boolean res = false;
			for (String s: getValidTypes())
				if (s.equalsIgnoreCase(type.toLowerCase())) res = true;
			return res;
		}
		public String[] getValidTypes() {
			return valid_types;
		}
		public void setMaxTail(String string) {
			if (testMaxTail(string)){
				int res = Integer.parseInt(string);
				this.maxtail = res;
			}
		}
		public int getMaxTail() {
			return maxtail;
		}
		public void setLang(String lng) {
			this.lang = testLang(lng);
		}
		public String getLang() {
			return lang;
		}
		public String testLang(String lang) {
			String res = "";
			Properties prop = new Properties();
			try {
				prop.load(getClass().getResourceAsStream("languages"));
				String lngs = prop.getProperty("languages");
				res = prop.getProperty("default");
				for (String lng:lngs.split(","))
					if (lng.equalsIgnoreCase(lang)) res = lng.toLowerCase();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			setLoc(prop.getProperty(res));
			return res;
		}
		public void setLoc(String locale) {
			this.locale = locale;
		}
		public String getLoc() {
			return locale;
		}
		public void setFont(String string) {
			try{
				this.font = Integer.parseInt(string);
			} catch (NumberFormatException e) {
				this.font = 12;
			}
		}
		public int getFont() {
			return font;
		}
	}
	public class MJName{
		private String name;
		private String wind;
		
		public MJName(String wind, String name){
			setName(name);
			setWind(wind);
		}
		public void setName(String name) {	this.name = name;	}
		public String getName() {	return name;	}
		public void setWind(String wind) {	this.wind = wind;	}
		public String getWind() {	return wind;	}
	}
	
	public class MJTail{
		private String _type;
		private String _num;
		private boolean _rotate;
		private boolean _red;
		private byte _pnt;
		private String locale;
		public MJTail(String number, String type, boolean rotate, boolean red, String locale){
			set_num(number);
			set_type(type);
			set_rotate(rotate);
			set_red(red);
			set_pnt(calc_pnt());
			setLoc(locale);
		}
		public MJTail(String str, String locale){
			set_num(str.substring(0, 1));
			set_type(str.substring(1, 2));
			if (str.length()>2){
				if (str.substring(2, 3).equalsIgnoreCase("r")) set_red(true);
				if (str.substring(2, 3).equalsIgnoreCase("~")) set_rotate(true);
				if (str.length()==4 && str.substring(3).equalsIgnoreCase("~")) set_rotate(true);
			}
			set_pnt(calc_pnt());
			setLoc(locale);
		}
		public MJTail(MJTail tail){
			set_num(tail.get_num());
			set_type(tail.get_type());
			set_rotate(tail.is_rotate());
			set_red(tail.is_red());
			set_pnt(calc_pnt());
			setLoc(tail.getLoc());
		}
		public byte calc_pnt() {
			byte res = 0;
			if (get_type().equalsIgnoreCase("b")){
				char a = get_num().charAt(0);
				res = (byte) (0x10 + a - 0x30);
			}
			if (get_type().equalsIgnoreCase("c")){
				char a = get_num().charAt(0);
				res = (byte) (0x20 + a - 0x30);
			}
			if (get_type().equalsIgnoreCase("s")){
				char a = get_num().charAt(0);
				res = (byte) (0x60 + a - 0x30);
			}
			if (get_type().equalsIgnoreCase("f")){
				char a = get_num().charAt(0);
				res = (byte) (0x70 + a - 0x30);
			}
			if (get_type().equalsIgnoreCase("w")){
				res = 0x40;
				if (get_num().equalsIgnoreCase("e")) res += 1;
				if (get_num().equalsIgnoreCase("s")) res += 2;
				if (get_num().equalsIgnoreCase("w")) res += 3;
				if (get_num().equalsIgnoreCase("n")) res += 4;
			}
			if (get_type().equalsIgnoreCase("d")){
				if (get_num().equalsIgnoreCase("r")||
					get_num().equalsIgnoreCase("w")||
					get_num().equalsIgnoreCase("g")){
					res = 0x50;
					if (get_num().equalsIgnoreCase("r")) res += 1;
					if (get_num().equalsIgnoreCase("w")) res += 2;
					if (get_num().equalsIgnoreCase("g")) res += 3;
				}else{
					char a = get_num().charAt(0);
					res = (byte) (0x30 + a - 0x30);
				}
			}
			if (get_type().equalsIgnoreCase("o")||
				get_type().equalsIgnoreCase("x")||
				get_type().equalsIgnoreCase("i")){
				res = 0;
			}
			return res;
		}
		public String toFile(){
			String res = "";
			res += get_num()+get_type();
			if (is_red()) res += "r";
			res += ".png";
			return res;
		}
		public String toString(){
			String res = "";
			if (get_type().equalsIgnoreCase("w")){
				if (get_num().equalsIgnoreCase("e")) res = MJUtils.getLocaleStr("tail.number.east", getLoc());
				if (get_num().equalsIgnoreCase("s")) res = MJUtils.getLocaleStr("tail.number.south", getLoc());
				if (get_num().equalsIgnoreCase("w")) res = MJUtils.getLocaleStr("tail.number.west", getLoc());
				if (get_num().equalsIgnoreCase("n")) res = MJUtils.getLocaleStr("tail.number.north", getLoc());
				res += " "+MJUtils.getLocaleStr("tail.type.wind", getLoc());
			}
			if (get_type().equalsIgnoreCase("d")){
				boolean fl = true;
				if (get_num().equalsIgnoreCase("r")){
					res = MJUtils.getLocaleStr("tail.number.red", getLoc());
					fl = false;
				}
				if (get_num().equalsIgnoreCase("g")){
					res = MJUtils.getLocaleStr("tail.number.green", getLoc());
					fl = false;
				}
				if (get_num().equalsIgnoreCase("w")){
					res = MJUtils.getLocaleStr("tail.number.white", getLoc());
					fl = false;
				}
				if (! fl){
					res += " "+MJUtils.getLocaleStr("tail.type.dragon", getLoc());
				}else{
					res = MJUtils.getLocaleStr("tail.type.dot", getLoc())+" "+MJUtils.getLocaleStr("tail.number."+get_num(), getLoc());
				}
			}
			if (get_type().equalsIgnoreCase("b")){
				res = MJUtils.getLocaleStr("tail.type.bamboo", getLoc())+" "+MJUtils.getLocaleStr("tail.number."+get_num(), getLoc());
			}
			if (get_type().equalsIgnoreCase("c")){
				res = MJUtils.getLocaleStr("tail.type.char", getLoc())+" "+MJUtils.getLocaleStr("tail.number."+get_num(), getLoc());
			}
			if (get_type().equalsIgnoreCase("f")){
				res = MJUtils.getLocaleStr("tail.type.flower", getLoc())+": "+MJUtils.getLocaleStr("tail.number.flower"+get_num(), getLoc());
			}
			if (get_type().equalsIgnoreCase("s")){
				res = MJUtils.getLocaleStr("tail.type.season", getLoc())+": "+MJUtils.getLocaleStr("tail.number.season"+get_num(), getLoc());
			}
			return res;
		}
		public void set_rotate(boolean _rotate) {
			this._rotate = _rotate;
		}
		public void set_red(boolean _red) {
			this._red = _red;
		}
		public boolean is_rotate() {
			return _rotate;
		}
		public boolean is_red() {
			return _red;
		}
		public void set_num(String num){
			_num = num.toLowerCase();
		}
		public String get_num(){
			return _num;
		}
		public void set_type(String type){
			_type = type.toLowerCase();
		}
		public String get_type(){
			return _type;
		}
		public void set_pnt(byte _pnt) {
			this._pnt = _pnt;
		}
		public byte get_pnt() {
			return _pnt;
		}
		public void setLoc(String locale) {
			this.locale = locale;
		}
		public String getLoc() {
			return locale;
		}
	}

	public class MJHand{
		private Vector<MJTail> hand = new Vector<MJTail>();
		private String wind;
		private int maxtiles = 14;
		private String locale;
		
		public MJHand(String locale){
			clear();
			setLoc(locale);
		}
		public MJHand(String wind, Vector<MJTail> hand, String locale){
			clear();
			setWind(wind);
			setHand(hand);
			setLoc(locale);
		}
		public void clear() {
			hand.clear();
		}
		public void add(MJTail tail){
			if (hand.size() < getMaxtiles())
				hand.add(tail);
		}
		public void discard(MJTail tail){
			boolean flag = false;
			int i;
			for (i=hand.size()-1; i>=0; i--){
				if (hand.get(i).get_type().equalsIgnoreCase(tail.get_type()) && hand.get(i).get_num().equalsIgnoreCase(tail.get_num())){
					hand.remove(hand.get(i));
					flag = true;
					break;
				}
			}
			if (!flag){
				for (MJTail t: hand){
					if (t.get_type().equalsIgnoreCase("i") && t.get_num().equalsIgnoreCase("i")){
						hand.remove(t);
						break;
					}
				}
			}
		}
		public void sort(){
			for(int i = 0; i < getHand().size(); i++) {
			    for(int j = getHand().size()-1; j > i; j-- ) {
			      if ( getTail(j-1).get_pnt() > getTail(j).get_pnt() ) {
			    	  MJTail temp = new MJTail(getTail(j-1).get_num(), getTail(j-1).get_type(), getTail(j-1).is_rotate(), getTail(j-1).is_red(),getLoc());

			    	  getTail(j-1).set_num(getTail(j).get_num()); 
			    	  getTail(j-1).set_type(getTail(j).get_type()); 
			    	  getTail(j-1).set_red(getTail(j).is_red()); 
			    	  getTail(j-1).set_rotate(getTail(j).is_rotate());
			    	  getTail(j-1).set_pnt(getTail(j).calc_pnt());
			    	  
			    	  getTail(j).set_num(temp.get_num()); 
			    	  getTail(j).set_type(temp.get_type()); 
			    	  getTail(j).set_red(temp.is_red()); 
			    	  getTail(j).set_rotate(temp.is_rotate());
			    	  getTail(j).set_pnt(temp.calc_pnt());
			      }
			    }
			}
		}
		public int size(){
			return this.hand.size();
		}
		public MJTail getTail(int index){
			if (index>=hand.size()) return null;
			return hand.get(index);
		}
		public void setMaxtiles(int maxtiles) {
			this.maxtiles = maxtiles;
		}
		public int getMaxtiles() {
			return maxtiles;
		}
		public void setWind(String wind) {
			this.wind = wind;
		}
		public String getWind() {
			return wind;
		}
		public void setHand(Vector<MJTail> hand) {
			this.hand = hand;
		}
		public Vector<MJTail> getHand() {
			return this.hand;
		}
		public void setLoc(String locale) {
			this.locale = locale;
		}
		public String getLoc() {
			return locale;
		}
		public boolean is_closed(){
			for (MJTail t: this.hand){
				if (t.get_type().equalsIgnoreCase("i") && t.get_num().equalsIgnoreCase("i"))
					return true;
			}
			return false;
		}
	}

	public class MJDiscard{
		private Vector<MJTail> discard = new Vector<MJTail>();
		private String wind;
		
		public MJDiscard(){
			clear();
		}
		public MJDiscard(String wind, Vector<MJTail> discard){
			clear();
			setWind(wind);
			setDiscard(discard);
		}
		public void clear() {
			discard.clear();
		}
		public void add(MJTail tail){
			discard.add(tail);
		}
		public void discard(MJTail tail){
			if (tail.get_type().equalsIgnoreCase(discard.lastElement().get_type()) && tail.get_num().equalsIgnoreCase(discard.lastElement().get_num())){
				discard.remove(discard.lastElement());
			}
		}
		public int size(){
			return discard.size();
		}
		public MJTail getTail(int index){
			if (index>=discard.size()) return null;
			return discard.get(index);
		}
		public void setWind(String wind) {
			this.wind = wind;
		}
		public String getWind() {
			return wind;
		}
		public void setDiscard(Vector<MJTail> discard) {
			this.discard = discard;
		}
		public Vector<MJTail> getDiscard() {
			return discard;
		}
	}
	
	public class MJLog{
		private String wind;
		private String action;
		private String tail;
		private String adv;
		private String suit;
		private String hand;
		private boolean closed;

		public void setWind(String wind) {
			this.wind = wind;
		}
		public String getWind() {
			return wind;
		}
		public void setAction(String action) {
			this.action = action;
		}
		public String getAction() {
			return action;
		}
		public void setTail(String tail) {
			this.tail = tail;
		}
		public String getTail() {
			return tail;
		}
		public void setAdv(String adv) {
			this.adv = adv;
		}
		public String getAdv() {
			return adv;
		}
		public void setSuit(String suit) {
			this.suit = suit;
		}
		public String getSuit() {
			return suit;
		}
		public void setHand(String hand) {
			this.hand = hand;
		}
		public String getHand() {
			return hand;
		}
		public void setClosed(boolean closed) {
			this.closed = closed;
		}
		public boolean isClosed() {
			return closed;
		}
	}
	
	public class MJPlayFile{
		private int from;
		private int to;
		public MJPlayFile(int from, int to){
			setFrom(from);
			setTo(to);
		}
		public void setFrom(int from) {
			this.from = from;
		}
		public int getFrom() {
			return from;
		}
		public void setTo(int to) {
			this.to = to;
		}
		public int getTo() {
			return to;
		}
	}
	
	public class lrUI extends BasicLabelUI
	{
		protected boolean clockwise;
		lrUI( boolean clockwise ){
			super();
			this.clockwise = clockwise;
		}
		

	    public Dimension getPreferredSize(JComponent c){
	    	Dimension dim = super.getPreferredSize(c);
	    	return new Dimension( dim.height, dim.width );
	    }	

	    private Rectangle paintIconR = new Rectangle();
	    private Rectangle paintTextR = new Rectangle();
	    private Rectangle paintViewR = new Rectangle();
	    private Insets paintViewInsets = new Insets(0, 0, 0, 0);

		public void paint(Graphics g, JComponent c){
	        JLabel label = (JLabel)c;
	        String text = label.getText();
	        Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();

	        if ((icon == null) && (text == null)) {
	            return;
	        }

	        FontMetrics fm = g.getFontMetrics();
	        paintViewInsets = c.getInsets(paintViewInsets);

	        paintViewR.x = paintViewInsets.left;
	        paintViewR.y = paintViewInsets.top;
	    	
	    	// Use inverted height & width
	        paintViewR.height = c.getWidth() - (paintViewInsets.left + paintViewInsets.right);
	        paintViewR.width = c.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);

	        paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
	        paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;

	        String clippedText = 
	            layoutCL(label, fm, text, icon, paintViewR, paintIconR, paintTextR);

	    	Graphics2D g2 = (Graphics2D) g;
	    	AffineTransform tr = g2.getTransform();
	    	if( clockwise )
	    	{
		    	g2.rotate( Math.toRadians(90) ); 
	    		g2.translate( 0, - c.getWidth() );
	    	}
	    	else
	    	{
		    	g2.rotate( Math.toRadians(270) ); 
	    		g2.translate( - c.getHeight(), 0 );
	    	}

	    	if (icon != null) {
	            icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
	        }

	        if (text != null) {
	            int textX = paintTextR.x;
	            int textY = paintTextR.y + fm.getAscent();

	            if (label.isEnabled()) {
	                paintEnabledText(label, g, clippedText, textX, textY);
	            }
	            else {
	                paintDisabledText(label, g, clippedText, textX, textY);
	            }
	        }
	    	g2.setTransform( tr );
	    }
	}
	
	public class xUI extends BasicLabelUI{
		xUI(){	super();	}

	    public Dimension getPreferredSize(JComponent c){
	    	Dimension dim = super.getPreferredSize(c);
	    	return new Dimension( dim.width, dim.height );
	    }	

	    private Rectangle paintIconR = new Rectangle();
	    private Rectangle paintTextR = new Rectangle();
	    private Rectangle paintViewR = new Rectangle();
	    private Insets paintViewInsets = new Insets(0, 0, 0, 0);

		public void paint(Graphics g, JComponent c){
	        JLabel label = (JLabel)c;
	        String text = label.getText();
	        Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();

	        if ((icon == null) && (text == null)) {
	            return;
	        }

	        FontMetrics fm = g.getFontMetrics();
	        paintViewInsets = c.getInsets(paintViewInsets);

	        paintViewR.x = paintViewInsets.right;
	        paintViewR.y = paintViewInsets.bottom;
	    	
	        paintViewR.height = c.getHeight() - (paintViewInsets.top + paintViewInsets.bottom);
	        paintViewR.width = c.getWidth() - (paintViewInsets.left + paintViewInsets.right);

	        paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
	        paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;

	        String clippedText = 
	            layoutCL(label, fm, text, icon, paintViewR, paintIconR, paintTextR);

	    	Graphics2D g2 = (Graphics2D) g;
	    	AffineTransform tr = g2.getTransform();
	    	g2.rotate( Math.PI ); 
    		g2.translate( -c.getWidth(), -c.getHeight());
    		
	    	if (icon != null) {
	            icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
	        }

	        if (text != null) {
	            int textX = paintTextR.x;
	            int textY = paintTextR.y + fm.getAscent();

	            if (label.isEnabled()) {
	                paintEnabledText(label, g, clippedText, textX, textY);
	            }
	            else {
	                paintDisabledText(label, g, clippedText, textX, textY);
	            }
	        }
	    	g2.setTransform( tr );
	    }
	}
}
